Modify window system exposes wrt outstanding moves
authorAlexander Larsson <alexl@redhat.com>
Thu, 13 Aug 2009 11:13:47 +0000 (13:13 +0200)
committerAlexander Larsson <alexl@redhat.com>
Thu, 13 Aug 2009 12:46:01 +0000 (14:46 +0200)
If there are outstanding moves in an area that intersects
the source of an outstanding move we need to move the invalid
area correspondingly, otherwise we will expose the wrong area
as the outstanding move copy will happen before we expose
the invalid area.

gdk/gdkinternals.h
gdk/gdkwindow.c

index 75eb068856b0d85a1c8f9839727d0d2c164eebc8..a668e682bcaa2a93b1120f22a8765373b7c14f08 100644 (file)
@@ -605,7 +605,7 @@ void _gdk_display_enable_motion_hints     (GdkDisplay *display);
 
 
 void _gdk_window_invalidate_for_expose (GdkWindow       *window,
-                                       const GdkRegion *region);
+                                       GdkRegion       *region);
 
 void _gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface,
                                            int width,
index cfb9d9edc95b8749bca79442db9209579d056676..04d8010061c0cb4760ea7b9f5322d79addc9f288 100644 (file)
@@ -5300,8 +5300,37 @@ gdk_window_invalidate_region (GdkWindow       *window,
  **/
 void
 _gdk_window_invalidate_for_expose (GdkWindow       *window,
-                                  const GdkRegion *region)
+                                  GdkRegion       *region)
 {
+  GdkWindowObject *private = (GdkWindowObject *) window;
+  GdkWindowRegionMove *move;
+  GdkRegion *move_region;
+  GList *l;
+
+  /* Any invalidations comming from the windowing system will
+     be in areas that may be moved by outstanding moves,
+     so we need to modify the expose region correspondingly,
+     otherwise we would expose in the wrong place, as the
+     outstanding moves will be copied before we draw the
+     exposes. */
+  for (l = private->outstanding_moves; l != NULL; l = l->next)
+    {
+      move = l->data;
+
+      /* covert to move source region */
+      move_region = gdk_region_copy (move->dest_region);
+      gdk_region_offset (move_region, -move->dx, -move->dy);
+
+      /* Move area of region that intersects with move source
+        by dx, dy of the move*/
+      gdk_region_intersect (move_region, region);
+      gdk_region_subtract (region, move_region);
+      gdk_region_offset (move_region, move->dx, move->dy);
+      gdk_region_union (region, move_region);
+
+      gdk_region_destroy (move_region);
+    }
+
   gdk_window_invalidate_maybe_recurse (window, region,
                                       (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
                                       NULL);